#ifndef DYNAMICARRAY_H
#define DYNAMICARRAY_H

#include "Array.h"
#include "Exception.h"

namespace DSLib
{

template <typename T>
class DynamicArray : public Array<T>
{
protected:
    int m_length;

    T* copy(T* pArray, int len, int newLen)
    {
        T* ret = new T[newLen];
        if (ret != NULL)
        {
            int size = len < newLen ? len : newLen;
            for (int i = 0; i < size; i++)
            {
                ret[i] = pArray[i];
            }
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "alloc memory failed!");
        }
        return ret;
    }

    void update(T* pArray, int length)
    {
        if (pArray != NULL)
        {
            T* pTemp = this->m_array;
            this->m_array = pArray;
            this->m_length = length;

            delete[] pTemp;
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "alloc memory failed!");
        }
    }

    void init(T* pArray, int length)
    {
        if (pArray != NULL)
        {
            this->m_array = pArray;
            this->m_length = length;
        }
        else
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "alloc memory failed!");
        }
    }

public:
    DynamicArray(int length = 0)
    {
        init(new T[length], length);
    }

    DynamicArray(const DynamicArray<T>& obj)
    {
        init(copy(obj.m_array, obj.m_length, obj.m_length), obj.m_length);
    }

    DynamicArray<T>& operator = (const DynamicArray<T>& obj)
    {
        if (this != &obj)
        {
            update(copy(obj.m_array, obj.m_length, obj.m_length), obj.m_length);
        }
        return *this;
    }


    void resize(int length)
    {
        if (m_length != length)
        {
            update(copy(this->m_array, this->m_length, length), length);
        }
    }

    int length() const
    {
        return m_length;
    }

    ~DynamicArray()
    {
        delete[] this->m_array;
    }
};

}
#endif // DYNAMICARRAY_H
